package com.story.aistory.config;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
import java.util.Base64;

import javax.crypto.spec.SecretKeySpec;

public class JWTSignature {

    private static final String PUBLIC_KEY = "hfSkfT3nhWlBPxnoHgB9Gkt9KWpTFpkxMk0AMbLSVCw";
    private static final String SECRET_KEY = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCatzY6lrxKrKfu\n" +
            "gOtaaj4A86KtBVzs5SDiCLt8h+vKWNJ9qqtHV3N+3a4ErPNESlG4IZYEVnxufXgV\n" +
            "HQwg/sM0PlgNEySoIhmrOfuV8mQzfOcA1Bsb+5HMJq4ozCPdroTgLXupvS0o6OO/\n" +
            "QZo+W7zPxBacam34ooLuAHdZ0p45dhju8rv/hEyfrKDkVgzXsGILxjQgftOJAQmz\n" +
            "JDHd0xzsQP2Syk9BWgzpt4413142PAGjFXfEanX8MLZ8H52zncsXsOIJliYg//c8\n" +
            "iDZS6KPS2hwqoud2GkqD+YVIoLBpPvuJ33a2UQIqJncFDQECO1ageWp5SLNN8ako\n" +
            "sZ19fuKhAgMBAAECggEAPkRORvYzgbpLO+oWzqTDn45ugkQOSilNOqtZCZ2KgD2P\n" +
            "OZReqq+/g+ekCa2xmmJu0TRzM/u6yJ0mnxi5sO3XkkclGN4Desd+nTMQ1iBfw3kZ\n" +
            "X3P+FR0CaK+ImFLQfH+oarDjfETuz/Aq+OZmNYKmUtgQYZNT/yUonLEDV9s0YttM\n" +
            "kt+tby8bEMV9dQ8JilmyDY/miTPQl0BG+vLS39f1/lCBvZqYeLE57llITMkNLURy\n" +
            "WPJGgO9TVWyKd6X027Utle/939C7p33kmQPcOlPH+3JBZHlUznmHRBNOhTn6ojQA\n" +
            "RR7s2VIEJBM9PlDjv5qvFUmoXffgvv7SdauuqN0+IQKBgQDOGa/E5YRjchs/lonZ\n" +
            "g5ZYLrrJeydHaB8dQjAnVuY13rAnRsKOOtUvKNZ2kxJgXA8v6SpwuohLdAfDNWx1\n" +
            "4Cq+XnT6gPwAkYNeWm76hXI4v1DiCmpHW7XRlCA/VGlyX4Sbd5+jn58k/CMVAjfT\n" +
            "pmmkX7dhI9uWpV8GAkV4Ljv6rwKBgQDALKZtXjTr5ZWXFown5qqmo31clMfOfH8s\n" +
            "s3qLtGYNRZA3I+w1TsqRMsFZHE3dkVO5Sv6Fpg0kCoeGTDVnA5IEnjyQ9bVxzpkh\n" +
            "oQbH0QjCW7m1hKtL77QBEv9fVtJhjzchAvX2udc8jEgqKxJXq89hMMFwJB5QOgIz\n" +
            "c3c1BxcLrwKBgG+VZJ57jPOyYaJJxJRpM8rGcgaHkLqOWtoibaO+3qCn0kNRgiAz\n" +
            "JhyERaio87gL34UW/g1OUGBZj6JWmEQxe7LZvQerMcS1A6Tf3VnxSegDXK0k6ml7\n" +
            "87JmOhdPgk+T+12YpGuYDjed8vh63PLQFD4UPFpxaX/kRNAiBq6MiZitAoGBAJCN\n" +
            "xY6FC4faRWDGHB0zfHAmkHjgjT98FGl6hBasVwtqpSVlBxu+Lc90f03ZZZTh6Tl6\n" +
            "+ONtWXsf1HunvY/EdsS0hliACsEVp8hNCP2q9kzElHe+2N8g6qTYNnHvrAaopM5X\n" +
            "HM8/UXEBEJNvnLeHzFGOTCNfd9HfIKK1GxkvQR2PAoGBAIKiDKO4/59lmxoSYtGP\n" +
            "JksWvhM4S9ES+UCyIUSloT5dF0t5guvCq6bCRdpVjcgN7deFJO/cpkv4udPTA96/\n" +
            "EE2IUzztFwlYi8VGHZBbB8Akp0UKNVVqfmICn7A6VWfrso5LGupdnA2XZZbNhCfp\n" +
            "0CR6+lnOPy3Yg82pz1LTAPDh\n" +
            "-----END PRIVATE KEY-----";

    // 读取公钥
    public static RSAPublicKey readPublicKeyFromString(String publicKeyPEM) throws Exception {
        byte[] bytes = Base64.getDecoder().decode(publicKeyPEM);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return (RSAPublicKey) publicKey;
    }

    // 读取私钥
    public static RSAPrivateKey readPrivateKeyFromPem(String pemEncoded) throws Exception {
        String pem = pemEncoded.replace("-----BEGIN PRIVATE KEY-----", "");
        pem = pem.replace("-----END PRIVATE KEY-----", "");
        pem = pem.replaceAll("\\s+","");
        byte[] decoded = Base64.getDecoder().decode(pem);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 将私钥字符串转换为RSAPrivateKey对象
        RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        return privateKey;
    }


    public static String generateJWT() throws Exception {
        JWTCreator.Builder jwtBuilder = JWT.create();

        // 编码前 JSON 格式的 Headers
        Map<String, Object> headers = new HashMap<>();
        headers.put("alg", "RS256"); // 加密算法，固定为RS256
        headers.put("typ", "JWT"); // token类型，固定为 JWT
        headers.put("kid", PUBLIC_KEY); // OAuth 应用的钥指纹
        // 签名
        // 使用私钥创建RS256算法实例
        Algorithm algorithm = Algorithm.RSA256(null, readPrivateKeyFromPem(SECRET_KEY));
        String token = jwtBuilder.withHeader(headers)
                .withClaim("iss", "1192008669375") // OAuth 应用的 ID
                .withClaim("aud", "api.coze.cn") // 扣子 API 的 Endpoint，即 api.coze.cn。
                .withClaim("iat", System.currentTimeMillis() / 1000L) // JWT开始生效的时间，秒级时间戳
                .withClaim("exp", System.currentTimeMillis() / 1000L + 1000) // JWT过期时间，秒级时间戳,1000s后失效
                .withClaim("jti", UUID.randomUUID().toString().replaceAll("-", "")) // 随机字符串，防止重放攻击
                .sign(algorithm);

        System.out.println("************** JWT  **************" + token);
        return token;
    }

    public static String getToken() throws Exception {
        String jwt = generateJWT();
        String requestUrl = "https://api.coze.cn/api/permission/oauth2/token";
        String bearerToken = "Bearer " + jwt;
        String jsonInputString = "{\"duration_seconds\": 86399, \"grant_type\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\"}";

        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(requestUrl);
        try {
            // 设置请求头
            httpPost.setHeader("Authorization", bearerToken);
            httpPost.setHeader("Content-Type", "application/json");

            // 设置请求体
            StringEntity entity = new StringEntity(jsonInputString);
            httpPost.setEntity(entity);

            // 发送请求并获取响应
            HttpResponse response = httpClient.execute(httpPost);
            int responseCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());

            System.out.println("POST Response Body :: " + responseBody);

            String token = JSONObject.parseObject(responseBody).getString("access_token");
            System.out.println("ACCESS_TOKEN :: " + token);

            return token;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
